package drds.plus.executor.data_node_executor.spi;

import drds.plus.common.lifecycle.AbstractLifecycle;
import drds.plus.common.model.DataNode;
import drds.plus.executor.ExecuteContext;
import drds.plus.executor.command_handler.CommandHandler;
import drds.plus.executor.command_handler.CommandHandlerFactory;
import drds.plus.executor.cursor.cursor.ISortingCursor;
import drds.plus.executor.cursor.cursor.impl.result_cursor.ResultCursor;
import drds.plus.executor.data_node_executor.DataNodeExecutorContext;
import drds.plus.executor.repository.Repository;
import drds.plus.sql_process.abstract_syntax_tree.execute_plan.ExecutePlan;
import lombok.Getter;
import lombok.Setter;

import java.util.List;
import java.util.concurrent.Future;

public abstract class AbstractDataNodeExecutor extends AbstractLifecycle implements DataNodeExecutor {
    @Setter
    @Getter
    private DataNode dataNode;
    @Setter
    @Getter
    private final Repository repository;


    public AbstractDataNodeExecutor(Repository repository) {
        this.repository = repository;
    }

    protected void doInit() throws RuntimeException {
        super.doInit();
    }

    public DataNode getDataNode() {
        return this.dataNode;
    }

    public ISortingCursor execute(ExecuteContext executeContext, ExecutePlan executePlan) throws RuntimeException {
        executeContext.setRepository(repository);
        CommandHandlerFactory commandExecutorFactory = this.repository.getCommandExecutorFactory();//不允许出现跨库事务
        CommandHandler commandHandler = commandExecutorFactory.getCommandHandler(executeContext, executePlan);  // 核心方法，用于根据当前executePlan,拿到对应的处理Handler
        return commandHandler.handle(executeContext, executePlan);
    }
    //

    public ResultCursor commit(ExecuteContext executeContext) throws RuntimeException {
        ResultCursor resultCursor = new ResultCursor(null, executeContext);
        executeContext.getTransaction().commit();
        return resultCursor;
    }

    public ResultCursor rollback(ExecuteContext executeContext) throws RuntimeException {
        ResultCursor resultCursor = new ResultCursor(null, executeContext);
        executeContext.getTransaction().rollback();
        return resultCursor;
    }


    //
    public Future<ISortingCursor> executeWithFuture(ExecuteContext executeContext, ExecutePlan executePlan) throws RuntimeException {
        return DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().executeWithFuture(executeContext, executePlan);
    }


    public Future<List<ISortingCursor>> executeWithFuture(ExecuteContext executeContext, List<ExecutePlan> executePlanList) throws RuntimeException {
        return DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().executeWithFuture(executeContext, executePlanList);
    }

    public Future<ResultCursor> commitWithFuture(ExecuteContext executeContext) throws RuntimeException {
        return DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().commitWithFuture(executeContext);
    }

    public Future<ResultCursor> rollbackWithFuture(ExecuteContext executeContext) throws RuntimeException {
        return DataNodeExecutorContext.getExecutorContext().getDataNodeExecutor().rollbackWithFuture(executeContext);
    }
}
